package game;

import java.util.List;

import menu.Menu;
import menu.Settings;

import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.UnicodeFont;
import org.newdawn.slick.font.effects.ColorEffect;
import org.newdawn.slick.openal.SoundStore;
import org.newdawn.slick.opengl.InternalTextureLoader;

import sound.SoundManager;
import entities.Player;

public class Specuspace extends BasicGame {

	private Player player;

	// initialize variables
	private Level[] levels;
	private int currentLevel;

	private boolean pendingLevelChange;
	private boolean paused;

	static UnicodeFont font;

	// input
	Input input;
	boolean upPressed;
	boolean rightPressed;
	boolean downPressed;
	boolean leftPressed;
	boolean confirmPressed;
	boolean cancelPressed;
	boolean firePressed;
	boolean rocketPressed;

	// key bindings
	int key_up = Input.KEY_UP;
	int key_right = Input.KEY_RIGHT;
	int key_down = Input.KEY_DOWN;
	int key_left = Input.KEY_LEFT;
	int key_confirm = Input.KEY_RETURN;
	int key_cancel = Input.KEY_BACK;
	int key_fire = Input.KEY_LCONTROL;
	int key_rocket = Input.KEY_LALT;
	int key_pause = Input.KEY_P;
	int key_quit = Input.KEY_Q;

	/**
	 * Constructor.
	 * 
	 * @param title
	 */
	public Specuspace(String title) {
		super(title);
	}

	@SuppressWarnings("unchecked")
	@Override
	public void init(GameContainer gc) throws SlickException {

		// create font
		String fontPath = "res/Axaxax.ttf";
		font = new UnicodeFont(fontPath, 20, true, false); // Create Instance
		font.addAsciiGlyphs(); // Add Glyphs
		font.addGlyphs(400, 600); // Add Glyphs
		font.getEffects().add(new ColorEffect(java.awt.Color.WHITE)); // Add
																		// Effects
		font.loadGlyphs(); // Load Glyphs

		SoundManager.getSoundManager().playMusic(SoundManager.mainTheme);
		SoundManager.getSoundManager().setVolume(.1f);

		player = new Player();

		// playing field
		List<EnemyWave> waves = WaveEditor.generateWaves(player);

		// create level
		levels = new Level[1];
		levels[0] = new Level(player, waves);

		enterLevel(0);

		// debug output

	}

	public void enterLevel(int level) {
		this.currentLevel = level;
		pendingLevelChange = true;
	}

	/*
	 * Main game loop
	 */

	@Override
	public void update(GameContainer gc, int delta) throws SlickException {

		input = gc.getInput();

		if (input.isKeyDown(key_quit)) {
			gc.exit();
		}
		
		if (levels[currentLevel].finished()
				&& currentLevel == levels.length - 1) {
			if (input.isKeyDown(Input.KEY_ENTER)) {
				gc.exit();
			}
		}

		if (input.isKeyPressed(key_pause)) {
			System.out.println("Game paused");
			if (paused) {
				paused = false;
				// SoundManager.getSoundManager().resume();
			} else {
				paused = true;
				// SoundManager.getSoundManager().pause();
			}
		}

		if (!paused) {

			Level level = levels[currentLevel];

			if (input.isKeyDown(key_up)) {
				level.getPlayer().moveUp();
			}
			if (input.isKeyDown(key_right)) {
				level.getPlayer().moveRight();
			}
			if (input.isKeyDown(key_down)) {
				level.getPlayer().moveDown();
			}
			if (input.isKeyDown(key_left)) {
				level.getPlayer().moveLeft();
			}

			if (input.isKeyDown(key_fire)) {
				// if (shotLock <= 0) {
				level.getPlayer().shoot();
				// shotLock = timeout;
				// }
			}

			if (!player.isAlive()) {
				if (player.getLives() <= 0) {
					System.out.println("Fail");
					enterLevel(0);
					levels[currentLevel].reset(gc);
					player.reset();
				} else {
					player.restoreLives();
					player.removeLife();
					enterLevel(currentLevel);
					levels[currentLevel].reset(gc);
					player.reset();

				}
			}

			if (pendingLevelChange) {
				level.reset(gc);
				pendingLevelChange = false;
			}

			// update level
			level.update(gc, delta);

		}

	}

	@Override
	public void render(GameContainer gc, Graphics g) throws SlickException {

		if (levels[currentLevel].finished()
				&& currentLevel == levels.length - 1) {
			SoundManager.getSoundManager().pause();
			new Image("res/youwin.png").draw(0, 0, gc.getWidth(), gc.getHeight());			
		} else {
			if (paused) {
				String msg = "Game paused";
				g.drawString(msg, gc.getWidth() / 2 - g.getFont().getWidth(msg)
						/ 2, gc.getHeight() / 2 - g.getFont().getHeight(msg)
						/ 2);
			} else {
				// draw level
				levels[currentLevel].render(gc, g);

				// draw hud
				font.drawString(60, 20, "Lives: "
						+ levels[currentLevel].getPlayer().getLives(), new Color(
						0x262d3c));
				font.drawString(650, 20, "Score: " + player.getPlayerScore(),
						new Color(0x262d3c));
				font.drawString(60, 550, "Difficulty: " + Settings.getDifficulty(),
						new Color(0x262d3c));
			}
			
		}
	}

	/**
	 * Main class for testing purposes.
	 * 
	 * @param args
	 * @throws SlickException
	 */
	public static void main(String[] args) throws SlickException {
//		 AppGameContainer menu = new AppGameContainer(new Menu("Specuspace"));
//		 menu.setForceExit(false);
//		 menu.setDisplayMode(800, 600, false);
//		 menu.start();
//		 menu.destroy();
//		 SoundStore.get().clear();
//		 InternalTextureLoader.get().clear();

		AppGameContainer game = new AppGameContainer(new Specuspace(
				"Specuspace"));
		game.setDisplayMode(800, 600, true);
		game.setShowFPS(false);
		SoundManager.loadFiles();
		game.start();
	}
}
